package com.jsoft.jsofted.sys.controller;

import com.diboot.core.util.V;
import com.diboot.file.util.HttpHelper;
import com.jsoft.jsofted.framework.annotation.JwtToken;
import com.jsoft.jsofted.framework.service.CocService;
import com.jsoft.jsofted.framework.utils.CocException;
import com.jsoft.jsofted.framework.utils.FileHelper;
import com.jsoft.jsofted.framework.utils.ResponseModel;
import com.jsoft.jsofted.sys.entity.FileEntity;
import com.jsoft.jsofted.sys.service.FileStorageService;
import com.jsoft.jsofted.sys.vo.UploadFileBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;

@RestController
@RequestMapping("/jsofted/file")
@Slf4j
public class FileController {

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private ApplicationContext context;

    protected CocService fileService() {
        return (CocService) context.getBean("fileService");
    }

    protected String buildAccessUrl(String fileUuid) {
        return "/jsofted/file/download/" + fileUuid;
    }

    @JwtToken
    @PostMapping("/upload")
    public ResponseModel upload(
            @RequestParam("file") MultipartFile file,
            HttpServletRequest request
    ) throws Exception {
        String relModule = request.getParameter("relModule");
        String relType = request.getParameter("relType");
        String relField = request.getParameter("relField");
        String relId = request.getParameter("relId");
        return uploadFile(file, relModule, relType, relField, relId);
    }

    protected ResponseModel uploadFile(
            MultipartFile file,
            String relModule,
            String relType,
            String relField,
            String relId
    ) throws Exception {
        if (file == null) {
            throw new CocException("上传的文件不存在！");
        }
        String originFileName = file.getOriginalFilename();
        if (V.isEmpty(originFileName) || !FileHelper.isValidFile(originFileName)) {
            throw new CocException("上传的文件格式不对！");
        }
        // 保存文件
        FileEntity fileEntity = saveDiskFile(file, relModule, relType, relField, relId);
        // 保存上传记录
        fileService().save(fileEntity);
        // 返回结果
        return ResponseModel.makeSuccess(new HashMap(16) {{
            put("id", fileEntity.getId());
            put("name", fileEntity.getName());
            put("url", fileEntity.getAccessUrl());
        }});
    }

    protected FileEntity saveDiskFile(
            MultipartFile file,
            String relModule,
            String relType,
            String relField,
            String relId
    ) throws Exception {
        UploadFileBean uploadFileBean = fileStorageService.upload(file);
        String accessUrl = buildAccessUrl(uploadFileBean.getUuid());
        FileEntity fileEntity = new FileEntity();
        fileEntity.setId(uploadFileBean.getUuid())
                .setName(uploadFileBean.getOriginalFilename())
                .setExtName(uploadFileBean.getExt())
                .setRelModule(relModule)
                .setRelType(relType)
                .setRelField(relField)
                .setRelId(relId)
                .setOriginType("1")
                .setIsImage(FileHelper.isImage(uploadFileBean.getFilename()))
                .setStoragePath(uploadFileBean.getStorageFullPath())
                .setAccessUrl(accessUrl)
                .setCreateTime(new Timestamp(new Date().getTime()));

        return fileEntity;
    }

    /**
     * 下载文件
     **/
    @GetMapping("/download/{fileUuid}")
    public ResponseModel download(@PathVariable("fileUuid") String fileUuid, HttpServletResponse response) throws Exception {
        FileEntity fileEntity = (FileEntity) fileService().getById(fileUuid);
        if (fileEntity == null) {
            return ResponseModel.makeError("待下载的文件不存在！");
        }
        if (fileEntity.getIsImage() != null && fileEntity.getIsImage()) {
            IOUtils.copy(FileUtils.openInputStream(new File(fileEntity.getStoragePath())), response.getOutputStream());
        } else {
            HttpHelper.downloadLocalFile(fileEntity.getStoragePath(), fileEntity.getName(), response);
        }

        return null;
    }

    @JwtToken
    @GetMapping("/remove/{fileUuid}")
    public ResponseModel remove(@PathVariable("fileUuid") String fileUuid) {
//        OpLogHolder.prepareLog("删除", null);

        FileEntity fileEntity = (FileEntity) fileService().getById(fileUuid);
        if (fileEntity != null) {
            fileService().removeById(fileUuid);
            FileHelper.deleteFile(fileEntity.getStoragePath());
            return ResponseModel.makeSuccess();
        } else {
            return ResponseModel.makeError("待删除的文件不存在！");
        }
    }
}
